//
//  MServerStreamDAO.m
//  MClient
//
//  Created by Zhouyi on 10-8-12.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "MServerStreamDAO.h"
#import "MServerJsonDAO.h"
#import "NSData+Base64.h"
#import "MCErrorManagement.h"

@interface MServerStreamDAO (Private)
//int dataLength; //huotianjun 转移到.h

- (void)sendAsyncStreamMessage;
@end

@implementation MServerStreamDAO
//@synthesize returnCode;
//@synthesize returnMessage;


static NSString *serverServletUrl = nil;
static NSArray *cookies = nil;

#pragma mark ---- 类基本方法 ----

- (id)init {
	if (self = [super init]) {
		[[NSNotificationCenter defaultCenter] addObserver:self
												 selector:@selector(delegateInvalid:)
													 name:@"viewControllerDealloc" object:nil];
	}
	return self;
}

- (void)delegateInvalid:(NSNotification *)notification
{
	MCViewController* controller = (MCViewController*)[notification object];
	if (controller == delegate) {
		delegate = nil;
	}
	MClientAppDelegate *appDelegate = (MClientAppDelegate*)[[UIApplication sharedApplication] delegate];
	[appDelegate stopActivityIndicatorView];
}

- (void)setTimeForTimeout
{
	_timeout = [NSTimer scheduledTimerWithTimeInterval:1000 //原值60,huotianjun
												target:self 
											  selector:@selector(timeoutManagement) 
											  userInfo:nil
											   repeats:NO];
}

- (void)dealloc {
	if (urlConnection) {
		[urlConnection cancel];
		[urlConnection release];
		urlConnection = nil;
	}
	delegate = nil;
	[_timeout invalidate]; _timeout = nil;
	[inParameters release]; inParameters = nil;
	[fileHandle closeFile]; [fileHandle release];fileHandle=nil;
	
	[[NSNotificationCenter defaultCenter] removeObserver:self 
													name:@"viewControllerDealloc" 
												  object:nil];
	[super dealloc];
}

- (void)uploadFileAsync:(NSString *)actionType location:(NSString *)location data:(NSInputStream *)data delegate:(id)aDelegate {
	[inParameters release];
	inParameters = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					actionType,@"actionType",
					location,@"location",
					data,@"data",
					nil];
	
	methodName = @"upload";
	delegate = aDelegate;
	
	[self sendAsyncStreamMessage];
}

- (void)downloadFileAsync:(NSString *)actionType dataFrom:(NSString *)dataFrom location:(NSString *)location fileName:(NSString *)fileName page:(int)page type:(NSString *)type saveLocation:(NSString *)saveLocation delegate:(id)aDelegate  {
	[inParameters release];
	inParameters = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					actionType,@"actionType",
					dataFrom,@"dataFrom",
					location,@"location",
					fileName,@"fileName",
					type,@"type",
					saveLocation,@"saveLocation",
					nil];
	if (page > 0) {
		[inParameters setObject:[NSString stringWithFormat:@"%d",page] forKey:@"page"];
	} 
	
	methodName = @"download";
	delegate = aDelegate;
	
	[self sendAsyncStreamMessage];
}

- (void)downloadFileWithUrlAsync:(NSString *)url saveLocation:(NSString *)saveLocation delegate:(id)aDelegate  {
	[inParameters release];
	inParameters = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					url,@"url",
					saveLocation,@"saveLocation",
					nil];
	
	methodName = @"downloadWithUrl";
	delegate = aDelegate;
	
	[self sendAsyncStreamMessage];
}

- (void)onException:(NSException*) e
{
	[_timeout invalidate], _timeout = nil;
	if (delegate && [delegate respondsToSelector:@selector(getServerError:returnMessage:)]) 
		[delegate getServerError:@"100" returnMessage:[e reason]];
	else {
		[[MCErrorManagement instance] doError:@"100" returnMessage:[e reason]];
	}
}

- (void)sendAsyncStreamMessage {
	@try {
		// 等待转圈图标开始转起来
		MClientAppDelegate *appDelegate = (MClientAppDelegate*)[[UIApplication sharedApplication] delegate];
		[appDelegate startActivityIndicatorView];
		
		NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
		
		serverServletUrl = [MServerJsonDAO getServerServletUrl];
		
		if (![methodName isEqualToString:@"downloadWithUrl"]) {
			[request setURL:[NSURL URLWithString:serverServletUrl]];
		}
		[request setTimeoutInterval:60];
		[request setCachePolicy:NSURLRequestUseProtocolCachePolicy];
		[request setValue:@"Keep-Alive" forHTTPHeaderField:@"Connection"];
		
		cookies = [MServerJsonDAO getCookies];
		
		if (cookies != nil) {
			NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
			[request setAllHTTPHeaderFields:headers];  
		}
		
		if ([methodName isEqualToString:@"upload"]) {
			
			NSString *actionType = [inParameters objectForKey:@"actionType"];
			NSString *location = [inParameters objectForKey:@"location"];
			NSInputStream *data = [inParameters objectForKey:@"data"]; 
			NSString *fileAction = [NSString stringWithFormat:@"action=%@;location=%@", actionType, location];
			MCLog(@"File-Action:\n%@",fileAction);
			const char *utfString = [fileAction UTF8String];
			NSData *requestData = [NSData dataWithBytes:utfString length:strlen(utfString)];
			[request setValue:[requestData base64Encoding] forHTTPHeaderField:@"File-Action"];		
			[request setHTTPMethod:@"POST"];
			[request setHTTPBodyStream:data];
		} else if ([methodName isEqualToString:@"download"]) {
			
			NSString *actionType = [inParameters objectForKey:@"actionType"];
			NSString *location = [inParameters objectForKey:@"location"];
			NSString *dataFrom = [inParameters objectForKey:@"dataFrom"];
			NSString *fileName = [inParameters objectForKey:@"fileName"];
			NSString *page = [inParameters objectForKey:@"page"];
			NSString *type = [inParameters objectForKey:@"type"];
			NSString *fileAction = [NSString stringWithFormat:@"action=%@;location=%@;fileName=%@;dataFrom=%@", actionType, location, fileName, dataFrom];
			
			if (page) {
				fileAction = [fileAction stringByAppendingFormat:@";page=%@", page];
			}
			if (![type isEqualToString:@""]) {
				fileAction = [fileAction stringByAppendingFormat:@";type=%@", type];
			}
			MCLog(@"File-Action:\n%@",fileAction);
			
			const char *utfString = [fileAction UTF8String];
			NSData *requestData = [NSData dataWithBytes:utfString length:strlen(utfString)];
			[request setValue:[requestData base64Encoding] forHTTPHeaderField:@"File-Action"];	
			[request setHTTPMethod:@"POST"];
			
			NSString *saveLocation = [inParameters objectForKey:@"saveLocation"];
			
			[fileHandle closeFile]; [fileHandle release]; fileHandle = nil;
			fileHandle = [[NSFileHandle fileHandleForWritingAtPath:saveLocation] retain];
			dataLength = 0;
		} else if ([methodName isEqualToString:@"downloadWithUrl"]) {
			NSString *saveLocation = [inParameters objectForKey:@"saveLocation"];
			[fileHandle closeFile]; [fileHandle release]; fileHandle = nil;
			fileHandle = [[NSFileHandle fileHandleForWritingAtPath:saveLocation] retain];
			dataLength = 0;
			NSString* url = [inParameters objectForKey:@"url"];
			[request setURL:[NSURL URLWithString:url]];
		}
		if (urlConnection) {
			[urlConnection cancel];
			[urlConnection release];
			urlConnection = nil;
		}
		[self setTimeForTimeout];
		[inParameters release]; inParameters = nil;
		
		urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
		[request release]; request = nil; 
	}
	@catch (NSException * e) {
		[self onException:e];
	}	
}

#pragma mark ----------------------------https 允许--------------------------------
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
	return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
	if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
		//if ([trustedHosts containsObject:challenge.protectionSpace.host])
		[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
	
	[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

-(void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
	//本次流量统计
	MCUserDefaults* defaults = [MCUserDefaults instance];
	//本次流量存入缓存
	defaults.currentReq += bytesWritten;
	//总流量存入缓存
	defaults.totalReq += bytesWritten;
	//本日流量存入缓存
	defaults.currentDayReq += bytesWritten;
	//本月流量存入缓存
	defaults.currentMonthReq += bytesWritten;
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
	@try {
		[_timeout invalidate],_timeout=nil;
		if ([methodName isEqualToString:@"upload"]) {
			
			NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
			int statusCode = [httpResponse statusCode];
			if (statusCode != 200) {
				if (delegate && [delegate respondsToSelector:@selector(getServerError:returnMessage:)]) {
					[delegate getServerError:@"1" returnMessage:@"文件上传失败！"];
				} else {
					[[MCErrorManagement instance] doError:@"99" returnMessage:@"文件上传失败！"];
				}
			}else {
				if (delegate && [delegate respondsToSelector:@selector(getDataFromServerSuccess:)]) {
					[delegate getDataFromServerSuccess:nil];
				}
			}
		}
		cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
		[cookies retain];
		
		NSHTTPURLResponse *httpResponse =(NSHTTPURLResponse*)response;
		NSDictionary *dictionary = [httpResponse allHeaderFields];
		if([dictionary objectForKey:@"Content-Page"]) {
			contentPage = [NSMutableDictionary dictionary];
			[contentPage setObject:[dictionary objectForKey:@"Content-Page"] forKey:@"Content-Page"];
			[contentPage retain];
		}
	}
	@catch (NSException * e) {
		if (urlConnection) {
			[urlConnection cancel];
			[urlConnection release];
			urlConnection = nil;
		}
		[self onException:e];
	}
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
	@try {
		[_timeout invalidate],_timeout=nil;
		dataLength = dataLength + [data length];
		[fileHandle writeData:data];
	}
	@catch (NSException * e) {
		if (urlConnection) {
			[urlConnection cancel];
			[urlConnection release];
			urlConnection = nil;
		}
		
		[self onException:e];
	}
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
	@try {
		[_timeout invalidate],_timeout=nil;
		MCUserDefaults* defaults = [MCUserDefaults instance];
		//本次流量存入缓存
		defaults.currentRes += dataLength;
		//总流量存入缓存
		defaults.totalRes += dataLength;
		//本日流量存入缓存
		defaults.currentDayRes += dataLength;
		//本月流量存入缓存
		defaults.currentMonthRes += dataLength;
		
		[fileHandle closeFile];	[fileHandle release]; fileHandle = nil;
		
		if (delegate && [delegate respondsToSelector:@selector(getServerError:returnMessage:)])  {
			[delegate getServerError:@"99" returnMessage:[error localizedDescription]];
		} else {
			[[MCErrorManagement instance] doError:@"99" returnMessage:[error localizedDescription]];
		}
	}
	@catch (NSException * e) {
		[self onException:e];
	}
	@finally {
		if (urlConnection) {
			[urlConnection cancel];
			[urlConnection release];
			urlConnection = nil;
		}
	}
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
	@try {
		[_timeout invalidate],_timeout=nil;
		MClientAppDelegate *appDelegate = (MClientAppDelegate*)[[UIApplication sharedApplication] delegate];
		[appDelegate stopActivityIndicatorView];
		if ([methodName isEqualToString:@"download"] ||
			[methodName isEqualToString:@"downloadWithUrl"]) {
			MCUserDefaults* defaults = [MCUserDefaults instance];
			//本次流量存入缓存
			defaults.currentRes += dataLength;
			//总流量存入缓存
			defaults.totalRes += dataLength;
			//本日流量存入缓存
			defaults.currentDayRes += dataLength;
			//本月流量存入缓存
			defaults.currentMonthRes += dataLength;
			
			[fileHandle closeFile];	[fileHandle release]; fileHandle = nil;
			if (delegate && [delegate respondsToSelector:@selector(getDataFromServerSuccess:)]) {
				[delegate getDataFromServerSuccess:contentPage];
			}
		}
	}
	@catch (NSException * e) {
		[self onException:e];
	}
	@finally {
		if (urlConnection) {
			[urlConnection cancel];
			[urlConnection release];
			urlConnection = nil;
		}
	}
}

-(void)timeoutManagement
{
	[_timeout invalidate],_timeout=nil;
	MClientAppDelegate *appDelegate = (MClientAppDelegate*)[[UIApplication sharedApplication] delegate];
	[appDelegate stopActivityIndicatorView];
	if (urlConnection) {
		[urlConnection cancel];
		[urlConnection release];
		urlConnection = nil;
	}
	[fileHandle closeFile];	[fileHandle release]; fileHandle = nil;
	
	if (delegate && [delegate respondsToSelector:@selector(getServerError:returnMessage:)]) 
		[delegate getServerError:@"100" returnMessage:@"网络链接超时！"];
	else {
		[[MCErrorManagement instance] doError:@"100" returnMessage:@"网络链接超时！"];
	}
}

@end


